package com.dup.jxlh.admin.handler;

import com.dup.jxlh.api.entities.CommonResult;
import com.dup.jxlh.api.enums.ResultEnum;
import com.dup.jxlh.api.exception.AppException;
import com.dup.jxlh.api.utils.ResultUtil;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(NoHandlerFoundException.class)
    public CommonResult noHandlerFoundExceptionHandler(NoHandlerFoundException e) {
        return ResultUtil.result(ResultEnum.REQUEST_NOT_EXIST, e.getRequestURL() + "接口不存在");
    }

    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public CommonResult httpRequestMethodExceptionHandler(HttpRequestMethodNotSupportedException e) {
        return ResultUtil.result(ResultEnum.REQUEST_NOT_SUPPORT, "不支持' " + e.getMethod() + "'请求");
    }
    @ExceptionHandler({ServletRequestBindingException.class})
    public CommonResult missingServletRequestParameterExceptionHandler(ServletRequestBindingException e) {
        return ResultUtil.result(ResultEnum.ARGS_ERROR, e.getMessage());
    }

    @ExceptionHandler(value = BindException.class)
    public CommonResult bindExceptionHandler(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        String errorMesssage = "";
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMesssage += fieldError.getDefaultMessage() + "!";
        }
        return ResultUtil.result(ResultEnum.ARGS_ERROR, errorMesssage);
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public CommonResult ConstraintViolationExceptionHandler(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();
        List<String> msgList = new ArrayList<>();
        while (iterator.hasNext()) {
            ConstraintViolation<?> cvl = iterator.next();
            msgList.add(cvl.getMessageTemplate());
        }
        return ResultUtil.result(ResultEnum.ARGS_ERROR, String.join(",", msgList));
    }

    @ExceptionHandler(InvalidGrantException.class)
    public CommonResult invalidGrantExceptionHandler(InvalidGrantException e) {
        return ResultUtil.result(ResultEnum.PASSWORD_ERROR, e.getMessage());
    }

    @ExceptionHandler(NullPointerException.class)
    public CommonResult nullPointerExceptionHandler(NullPointerException e) {
        return ResultUtil.result(ResultEnum.REQUEST_NULL_POINTER, e.getMessage());
    }

    @ExceptionHandler(AppException.class)
    public CommonResult appExceptionHandler(AppException e) {
        return ResultUtil.result(e.getResultEnum(), e.getMessage());
    }

}
